package main

import (
	"fmt"
	"sync"
	"time"
)

type PersonInfo struct {
	Name string
	Age  int
}

type MapArray struct {
	list map[int][]int
}

var (
	gma  = &MapArray{}
	wait = sync.WaitGroup{}
)

func ParallelRead() {
	defer wait.Done()
	for i := 0; i < 10; i++ {
		fmt.Println(gma.list[1])
	}
}

func ParallelWrite() {
	defer wait.Done()
	for i := 0; i < 10; i++ {
		gma.list[1] = append(gma.list[1], 1)
	}
}

func main() {
	PersonMap := make(map[string]PersonInfo)

	PersonMap["10001"] = PersonInfo{"Astone", 23}
	PersonMap["10002"] = PersonInfo{"Ray", 21}

	for key, val := range PersonMap {
		fmt.Println("key:", key, "val:", val.Name, val.Age)
	}

	Person, err := PersonMap["10001"]
	if !err {
		fmt.Println("Can't found person")
	}
	fmt.Println(Person, err)
	fmt.Println(PersonMap["123"])

	delete(PersonMap, "10001")
	for key, val := range PersonMap {
		fmt.Println("key:", key, "val:", val.Name, val.Age)
	}

	m := sync.Map{}
	m.Store("10001", PersonInfo{"Astone", 23})
	fmt.Println(m.Load("10001"))
	m.Range(func(k, v interface{}) bool {
		fmt.Println(k, v)
		return true
	})
	m.Delete("10001")
	fmt.Println(m.Load("10001"))
	m.Delete("10001")

	/////////////////////////////////////////////////
	// sync.Map Range
	fmt.Println("Start sync.Map Parallel")
	m.Store("10001", PersonInfo{"Astone", 23})
	go m.Range(func(k, v interface{}) bool {
		time.Sleep(5 * time.Second)
		fmt.Println(k, v)
		return true
	})
	time.Sleep(1 * time.Second)
	fmt.Println(m.Load("10001"))

	/////////////////////////////////////////////////

	ma := &MapArray{}
	ma.list = make(map[int][]int)
	ma.list[1] = append(ma.list[1], 1)
	ma.list[1] = append(ma.list[1], 2)
	fmt.Println(ma)

	/////////////////////////////////////////////////

	// go run -race main.go
	gma.list = make(map[int][]int)
	gma.list[1] = append(gma.list[1], 1)
	gma.list[1] = append(gma.list[1], 2)

	for i := 0; i < 10; i++ {
		wait.Add(1)
		go ParallelRead()
	}
	/*
		wait.Add(1)
		go ParallelWrite()
	*/

	wait.Wait()

}
